home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / disk / misc / TurboDevice.lha / TurboDevice / Turbo.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-07  |  14.9 KB  |  545 lines

  1. /*
  2.   ##########################################################################
  3.   ####                                                                  ####
  4.   ####         TurboDevice - A resident RAM disk for the Amiga          ####
  5.   ####        =================================================         ####
  6.   ####                                                                  ####
  7.   #### Format.c                                                         ####
  8.   ####                                                                  ####
  9.   #### Version 1.00os  --  May 04, 1991                                 ####
  10.   ####                                                                  ####
  11.   #### Copyright (C) 1990  Thomas Dreibholz                             ####
  12.   ####               1991  Molbachweg 7                                 ####
  13.   ####                     51674 Wiehl/Germany                          ####
  14.   ####                     EMail: Dreibholz@bigfoot.com                 ####
  15.   ####                     WWW:   http://www.bigfoot.com/~dreibholz     ####
  16.   ####                                                                  ####
  17.   ##########################################################################
  18. */
  19. /***************************************************************************
  20.  *                                                                         *
  21.  *   This program is free software; you can redistribute it and/or modify  *
  22.  *   it under the terms of the GNU General Public License as published by  *
  23.  *   the Free Software Foundation; either version 2 of the License, or     *
  24.  *   (at your option) any later version.                                   *
  25.  *                                                                         *
  26.  ***************************************************************************/
  27.  
  28.  
  29. #include <exec/types.h>
  30. #include <libraries/dos.h>
  31. #include <libraries/dosextens.h>
  32. #include <libraries/filehandler.h>
  33. #include <exec/memory.h>
  34. #include <exec/execbase.h>
  35. #include <exec/resident.h>
  36. #include <exec/devices.h>
  37. #include <exec/io.h>
  38. #include <exec/libraries.h>
  39. #include <devices/trackdisk.h>
  40.  
  41. /* Resident-Informationen */
  42.  
  43. #define MODULENAME     "turbo.semaphore"
  44. #define IDSTRING       "turbo.semaphore 37.0 (1 Aug 1991)\n"
  45. #define TURBO_NUMUNITS 50
  46. #define TURBO_VERSION  37
  47. #define TURBO_PRIORITY 35
  48.  
  49. /* Interne Verwaltungsstrukturen */
  50.  
  51. struct MemoryPtr
  52. {
  53.  UBYTE *Address;
  54.  ULONG  Length;
  55. };
  56. struct TurboMod
  57. {
  58.  struct MemChunk  tm_OverwriteMe;
  59.  APTR             tm_ModuleTab[3];
  60.  struct Resident  tm_ROMTag;
  61.  struct MemoryPtr tm_MemoryPtr[TURBO_NUMUNITS];
  62.  struct MemList   tm_ML;
  63.  struct MemEntry  tm_NextList[TURBO_NUMUNITS];
  64.  UBYTE            tm_ModuleName[20];
  65.  UBYTE            tm_IdString[40];
  66. };
  67. struct MatchTag
  68. {
  69.  struct Resident  mt_ROMTag;
  70.  struct MemoryPtr mt_MemoryPtr[TURBO_NUMUNITS];
  71.  struct MemList   mt_ML;
  72.  struct MemEntry  mt_NextList[TURBO_NUMUNITS];
  73.  UBYTE            mt_ModuleName[20];
  74.  UBYTE            mt_IdString[40];
  75. };
  76. struct InfoTable
  77. {
  78.  struct DeviceNode        *DeviceNode;
  79.  struct FileSysStartupMsg *FSSM;
  80.  struct DosEnvec          *DosEnvec;
  81.  ULONG                     MemoryType;
  82.  struct DosLibrary        *DosBase;
  83. };
  84.  
  85. /* Hauptstruktur des Devices */
  86.  
  87. struct TurboDevice
  88. {
  89.  struct Library     Device;
  90.  struct ExecBase   *SysLib;
  91.  struct DosLibrary *DosLib;
  92.  APTR               SegList;
  93.  struct Resident   *Resident;
  94.  UBYTE              Flags;
  95.  UBYTE              DriveNum;
  96.  struct TurboUnit  *Units[TURBO_NUMUNITS];
  97. };
  98. struct TurboDevMsg
  99. {
  100.  struct Device     *tdm_Device;
  101.  struct Unit       *tdm_Unit;
  102. };
  103. struct TurboUnit
  104. {
  105.  struct Unit        tu_Unit;
  106.  UBYTE              tu_UnitNum;
  107.  UBYTE              tu_pad;
  108.  struct TurboDevMsg tu_Message;
  109.  struct Process    *tu_Process;
  110.  LONG               tu_LastComm;
  111.  ULONG              tu_Size;
  112.  ULONG              tu_NumTracks;
  113.  ULONG              tu_Position;
  114. };
  115.  
  116. /* Flags für MountList */
  117.  
  118. #define TDB_RAM 0L
  119. #define TDB_TYPE 1L
  120. #define TDF_RESIDENT 0L
  121. #define TDF_RAM (1L<<0)
  122. #define TDF_TYPE (1L<<1)
  123.  
  124. /* Berechnungsmacros */
  125.  
  126. #define DE(x) (info.DosEnvec->x)
  127. #define TRACKS (((DE(de_HighCyl)+1)-DE(de_LowCyl))*DE(de_Surfaces))
  128.  
  129. /* Funktionsvordefinitionen */
  130.  
  131. VOID   ResetProg();
  132. VOID   EndCode();
  133. UBYTE *GetMemory();
  134. ULONG  GetDriveSize();
  135. VOID RootBlockCheckSum();
  136. VOID AllocBitMapBlock();
  137. VOID FreeBitMapBlock();
  138. VOID CalcBitMapCheckSum();
  139. ULONG CalcRootBlock();
  140. ULONG CalcBitMap();
  141. ULONG CalcBlocks();
  142. VOID InstallRootBlock();
  143. VOID Format();
  144.  
  145. /* ================================================== */
  146. /* == GetMemory                                    == */
  147. /* == Beschafft und installiert Speicher           == */
  148. /* == Parameter:                                   == */
  149. /* ==   =>  EBase:    Zeiger auf ExecBase          == */
  150. /* ==   =>  Device:   Zeiger auf TurboDevice       == */
  151. /* ==   =>  Unit:     Unitnummer                   == */
  152. /* ==   =>  TurboUnit: Zeiger auf Unit             == */
  153. /* ==   <=  Kapazität des Units                    == */
  154. /* ================================================== */
  155.  
  156. UBYTE *GetMemory(EBase,Device,Unit,TurboUnit)
  157.  struct ExecBase *EBase;
  158.  struct TurboDevice *Device;
  159.  ULONG Unit;
  160.  struct TurboUnit *TurboUnit;
  161. {
  162.  register struct TurboMod *tm;
  163.  register struct Resident *res;
  164.  register struct MatchTag *mt;
  165.  UBYTE *copydest,*copysrc;
  166.  register UBYTE *mem;
  167.  register ULONG Size;
  168.  struct InfoTable info;
  169.  
  170.  info.DosBase=OpenLibrary("dos.library",0L);
  171.  res=FindResident(MODULENAME);
  172.  if(res==NULL) res=Device->Resident;
  173.  if(res!=NULL)
  174.   {
  175.    mt=(struct MatchTag *)res->rt_MatchTag;
  176.    mem=mt->mt_MemoryPtr[Unit].Address;
  177.    if(mem==NULL)
  178.     {
  179.      Size=GetDriveSize(FindTask(NULL),Unit,&info);
  180.      if(Size==NULL) return(NULL);
  181.      Size+=8;
  182.      mem=AllocMem(Size,info.MemoryType);
  183.      if(mem==NULL) return(NULL);
  184.      TurboUnit->tu_Size=Size-8;
  185.      TurboUnit->tu_NumTracks=TRACKS;
  186.      if(info.FSSM->fssm_Flags & TDF_RAM)
  187.       {
  188.        mem=mem+8;
  189.        Format(mem,&info,Device->DriveNum);
  190.        Device->DriveNum++;
  191.        return(mem);
  192.       }
  193.      mt->mt_MemoryPtr[Unit].Address=mem+8;
  194.      mt->mt_MemoryPtr[Unit].Length=Size-8;
  195.      mt->mt_ML.ml_ME[mt->mt_ML.ml_NumEntries].me_Addr=mem;
  196.      mt->mt_ML.ml_ME[mt->mt_ML.ml_NumEntries].me_Length=Size;
  197.      mt->mt_ML.ml_NumEntries++;
  198.      Forbid();
  199. #asm
  200.      movem.l d0/a6,-(sp)
  201.      move.l $4,a6
  202.      jsr -612(a6)
  203.      move.l d0,554(a6)
  204.      movem.l (sp)+,d0/a6
  205. #endasm
  206.      Permit();
  207.      mem=mem+8;
  208.      Format(mem,&info,Device->DriveNum);
  209.      Device->DriveNum++;
  210.     }
  211.    return(mem);
  212.   }
  213.  Size=GetDriveSize(FindTask(NULL),Unit,&info);
  214.  if(Size==NULL) return(NULL);
  215.  Size+=8;
  216.  mem=AllocMem(Size,info.MemoryType);
  217.  if(mem==NULL)
  218.   {
  219.    return(NULL);
  220.   }
  221.  TurboUnit->tu_Size=Size-8;
  222.  if(info.FSSM->fssm_Flags & TDF_RAM) return(mem+8);
  223.  tm=AllocMem(sizeof(struct TurboMod)+((ULONG)EndCode-(ULONG)ResetProg),MEMF_CHIP|MEMF_CLEAR);
  224.  if(tm==NULL)
  225.   {
  226.    Size-=8;
  227.    FreeMem(mem,Size);
  228.    return(NULL);
  229.   }
  230.  tm->tm_ROMTag.rt_MatchWord=RTC_MATCHWORD;
  231.  tm->tm_ROMTag.rt_MatchTag=&tm->tm_ROMTag;
  232.  tm->tm_ROMTag.rt_EndSkip=(APTR)((UBYTE *)tm+sizeof(struct TurboMod))+((ULONG)EndCode-(ULONG)ResetProg);
  233.  tm->tm_ROMTag.rt_Flags=RTF_COLDSTART;
  234.  tm->tm_ROMTag.rt_Version=TURBO_VERSION;
  235.  tm->tm_ROMTag.rt_Type=NT_SEMAPHORE;
  236.  tm->tm_ROMTag.rt_Pri=TURBO_PRIORITY;
  237.  tm->tm_ROMTag.rt_Name=tm->tm_ModuleName;
  238.  tm->tm_ROMTag.rt_IdString=tm->tm_IdString;
  239.  tm->tm_ROMTag.rt_Init=(APTR)((UBYTE *)tm+sizeof(struct TurboMod));
  240.  tm->tm_ML.ml_NumEntries=2;
  241.  tm->tm_ML.ml_Node.ln_Type=NT_MEMORY;
  242.  tm->tm_ML.ml_ME[0].me_Addr=(APTR)tm;
  243.  tm->tm_ML.ml_ME[0].me_Length=sizeof(struct TurboMod)+((ULONG)EndCode-(ULONG)ResetProg);
  244.  tm->tm_ML.ml_ME[1].me_Addr=mem;
  245.  tm->tm_ML.ml_ME[1].me_Length=Size;
  246.  tm->tm_MemoryPtr[Unit].Address=mem+8;
  247.  tm->tm_MemoryPtr[Unit].Length=Size-8;
  248.  strcpy(tm->tm_ModuleName,MODULENAME);
  249.  strcpy(tm->tm_IdString,IDSTRING);
  250.  copysrc=(UBYTE *)ResetProg;
  251.  copydest=(UBYTE *)tm->tm_ROMTag.rt_Init;
  252.  while(copysrc!=(UBYTE *)EndCode) *copydest++ = *copysrc++;
  253.  Device->Resident=&tm->tm_ROMTag;
  254.  Forbid();
  255.  tm->tm_ModuleTab[0]=(APTR)&tm->tm_ROMTag;
  256.  if(EBase->KickTagPtr)
  257.   {
  258.    tm->tm_ModuleTab[1]=(APTR)((ULONG)EBase->KickTagPtr|1<<31);
  259.   }
  260.  else
  261.   {
  262.    tm->tm_ModuleTab[1]=NULL;
  263.   }
  264.  if(EBase->KickMemPtr)
  265.   {
  266.    tm->tm_ML.ml_Node.ln_Succ=(struct Node *)EBase->KickMemPtr;
  267.   }
  268.  EBase->KickTagPtr=(APTR)tm->tm_ModuleTab;
  269.  EBase->KickMemPtr=(APTR)&tm->tm_ML;
  270. #asm
  271.  movem.l d0/a6,-(sp)
  272.  move.l $4,a6
  273.  jsr -612(a6)
  274.  move.l d0,554(a6)
  275.  movem.l (sp)+,d0/a6
  276. #endasm
  277.  Permit();
  278.  InitResident(&tm->tm_ROMTag,tm);
  279.  mem=mem+8;
  280.  Format(mem,&info,Device->DriveNum);
  281.  Device->DriveNum++;
  282.  return(mem);
  283. }
  284.  
  285. /* ================================================== */
  286. /* == ResetProg                                    == */
  287. /* == Diese Funktion läßt den Bildschirm für einen == */
  288. /* == kurzen Moment gelb werden, wenn das erste    == */
  289. /* == resetfeste Unit installiert wird und wenn    == */
  290. /* == ein resetfestes Unit bei einem Reset verfüg- == */
  291. /* == bar ist. Sollte trotz resetfestem Unit kein  == */
  292. /* == gelber Bildschirm auftreten, so wurden die   == */
  293. /* == Zeiger auf die resetfesten Strukturen        == */
  294. /* == zerstört! Die in den Units gespeicherten     == */
  295. /* == Daten sind Verloren!                         == */
  296. /* ================================================== */
  297.  
  298. /* Anfang des resetfesten Bereichs */
  299.  
  300. VOID ResetProg()
  301. {
  302. #asm
  303.    move.l d0,-(sp)         ; d0 retten
  304.    move.l #$10000,d0       ; $10000 nach d0
  305. 1$:                        ; Schleife
  306.    move.w #$0FF5,$DFF180   ; Farbe gelb in Farbregister 0
  307.    subq.l #1,d0            ; 1 von d0 abziehen
  308.    tst.l d0                ; Ist d0=0 ?
  309.    bne 1$                  ; Nein, dann zu Schleife
  310.    move.l (sp)+,d0         ; d0 freigeben
  311. #endasm
  312. }
  313.  
  314. /* Ende des resetfesten Bereichs */
  315.  
  316. VOID EndCode() {} /* Markierung für Ende des Bereichs */
  317.  
  318. /* ================================================== */
  319. /* == Format                                       == */
  320. /* == Diese Routine formatiert den belegten        == */
  321. /* == Speicher im AmigaDOS-Format. Sie wird nach   == */
  322. /* == jeder Belegung aufgerufen.                   == */
  323. /* ================================================== */
  324.  
  325. VOID Format(amem,info,number)
  326.  ULONG amem;
  327.  struct InfoTable *info;
  328.  ULONG number;
  329. {
  330.  REGISTER ULONG a,b,c,d;
  331.  REGISTER UBYTE *bmem;
  332.  REGISTER ULONG cmem;
  333.  UBYTE Name[15];
  334.  bmem=(UBYTE *)amem;
  335.  bmem[0]='D';
  336.  bmem[1]='O';
  337.  bmem[2]='S';
  338.  bmem[3]=0x00;
  339.  a=CalcRootBlock(info->DosEnvec);
  340.  b=CalcBitMap(info->DosEnvec);
  341.  cmem=amem+(a*512L);
  342.  strcpy(&Name,"Turbo #xy");
  343.  if(number>9)
  344.   {
  345.    c=number/10;
  346.    Name[7]=c+0x30;
  347.    c=number%10;
  348.    Name[8]=c+0x30;
  349.   }
  350.  else
  351.   {
  352.    Name[7]=number+0x30;
  353.    Name[8]=0x00;
  354.   }
  355.  InstallRootBlock(info->DosBase,cmem,&Name,b);
  356.  cmem=amem+(b*512);
  357.  d=CalcBlocks(info->DosEnvec);
  358.  for(c=2;c<=d;c++)
  359.   {
  360.    FreeBitMapBlock(c,cmem);
  361.   }
  362.  AllocBitMapBlock(a,cmem);
  363.  AllocBitMapBlock(b,cmem);
  364.  CalcBitMapCheckSum(cmem);
  365. }
  366.  
  367. /* ================================================== */
  368. /* == GetDriveSize                                 == */
  369. /* == Kapazität des Units ermitteln                == */
  370. /* == Parameter:                                   == */
  371. /* ==   => DosBase:  Zeiger auf DosLibrary         == */
  372. /* ==   => Task:     Zeiger auf Unit-Task          == */
  373. /* ==   => Unit:     Unitnummer                    == */
  374. /* ==   => Info:     Zeiger auf InfoTable          == */
  375. /* ==   <= Kapazität                               == */
  376. /* ================================================== */
  377.  
  378. ULONG GetDriveSize(task,unit,info)
  379.  ULONG task;
  380.  ULONG unit;
  381.  struct InfoTable *info;
  382. {
  383.  register struct DosBase *DosBase;
  384.  register struct DeviceNode *DeviceNode;
  385.  register struct RootNode *RootNode;
  386.  register struct DosInfo *DosInfo;
  387.  register struct FileSysStartupMsg *FSSM;
  388.  register struct DosEnvec *DosEnvec;
  389.  register ULONG size;
  390.  
  391.  DosBase=info->DosBase;
  392.  task=task+92;
  393.  size=64*1024*1024;
  394.  RootNode=DosBase->dl_Root;
  395.  DosInfo=BADDR(RootNode->rn_Info);
  396.  DeviceNode=BADDR(DosInfo->di_DevInfo);
  397.  do
  398.   {
  399.    if(DeviceNode->dn_Type==DLT_DEVICE)
  400.     {
  401.      if(DeviceNode->dn_Task==task)
  402.       {
  403.        FSSM=BADDR(DeviceNode->dn_Startup);
  404.        if(FSSM->fssm_Unit==unit)
  405.         {
  406.          DosEnvec=BADDR(FSSM->fssm_Environ);
  407.          size=(DosEnvec->de_HighCyl+1)-DosEnvec->de_LowCyl;
  408.          size=size*DosEnvec->de_BlocksPerTrack;
  409.          size=size*DosEnvec->de_Surfaces;
  410.          size=size*DosEnvec->de_SizeBlock*4;
  411.          size=size+(DosEnvec->de_Reserved*DosEnvec->de_SizeBlock*4);
  412.          size=size+(DosEnvec->de_PreAlloc*DosEnvec->de_SizeBlock*4);
  413.          info->DeviceNode=DeviceNode;
  414.          info->FSSM=FSSM;
  415.          info->DosEnvec=DosEnvec;
  416.          if(FSSM->fssm_Flags & TDF_TYPE)
  417.           {
  418.            switch(DosEnvec->de_BufMemType)
  419.             {
  420.              case 2:
  421.              case 3:
  422.               info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC|MEMF_CHIP;
  423.               break;
  424.              case 4:
  425.              case 5:
  426.               info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC|MEMF_FAST;
  427.               break;
  428.              default:
  429.               info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC;
  430.               break;
  431.             }
  432.           } 
  433.          else
  434.           {
  435.            info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC;
  436.           }
  437.          DeviceNode=NULL;
  438.         }
  439.        else
  440.         {
  441.          DeviceNode=BADDR(DeviceNode->dn_Next);
  442.         }
  443.       }
  444.      else
  445.       {
  446.        DeviceNode=BADDR(DeviceNode->dn_Next);
  447.       }
  448.     }
  449.    else
  450.     {
  451.      DeviceNode=BADDR(DeviceNode->dn_Next);
  452.     }
  453.   }
  454.  while(DeviceNode!=0L);
  455.  return(size);
  456. }
  457.  
  458. VOID RootBlockCheckSum(buf)
  459.  UBYTE *buf;
  460. {
  461.  ULONG checksum,*long_ptr;
  462.  LONG i;
  463.  long_ptr=(ULONG *)buf;
  464.  checksum=0;
  465.  for(i=0;i<TD_SECTOR/4;i++)
  466.   {
  467.    checksum+=long_ptr[i];
  468.   }
  469.  long_ptr[5]-=checksum;
  470. }
  471.  
  472. VOID InstallRootBlock(DBase,buf,diskname,bitmap)
  473.  struct DosLibrary *DBase;
  474.  UBYTE *buf;
  475.  UBYTE *diskname;
  476.  ULONG bitmap;
  477. {
  478.  ULONG *long_ptr;
  479.  LONG i;
  480.  long_ptr=(ULONG *)buf;
  481.  long_ptr[0]   =  2L;
  482.  long_ptr[3]   =  72L;
  483.  long_ptr[78]  = -1L;
  484.  long_ptr[79]  =  bitmap;
  485.  long_ptr[127] =  1L;
  486.  DateStamp(DBase,&long_ptr[121]);
  487.  DateStamp(DBase,&long_ptr[105]);
  488.  buf[432]=(UBYTE)strlen(diskname);
  489.  for(i=0;i<strlen(diskname);i++)
  490.   {
  491.    buf[433+i]=diskname[i];
  492.   }
  493.  RootBlockCheckSum(buf);
  494. }
  495.  
  496. ULONG CalcRootBlock(env)
  497.  struct DosEnvec *env;
  498. {
  499.  return((env->de_HighCyl+1)*env->de_Surfaces*env->de_BlocksPerTrack/2);
  500. }
  501.  
  502. ULONG CalcBitMap(env)
  503.  struct DosEnvec *env;
  504. {
  505.  return((CalcRootBlock(env)+1));
  506. }
  507.  
  508. ULONG CalcBlocks(env)
  509.  struct DosEnvec *env;
  510. {
  511.  return((env->de_HighCyl+1)*env->de_Surfaces*env->de_BlocksPerTrack-1);
  512.  
  513. VOID AllocBitMapBlock(block,buf)
  514.  LONG block;
  515.  UBYTE *buf;
  516. {
  517.  ULONG *long_ptr=(ULONG *)buf;
  518.  REGISTER LONG longword,bit;
  519.  longword=(block-2)/32;
  520.  bit=block-2-longword*32;
  521.  long_ptr[longword+1] &= (0xFFFFFFFF-(1L<<bit));
  522. }
  523.  
  524. VOID FreeBitMapBlock(block,buf)
  525.  LONG block;
  526.  UBYTE *buf;
  527. {
  528.  ULONG *long_ptr=(ULONG *)buf;
  529.  REGISTER LONG longword,bit;
  530.  longword=(block-2)/32;
  531.  bit=block-2-longword*32;
  532.  long_ptr[longword+1] |= (1L<<bit);
  533. }
  534.  
  535. VOID CalcBitMapCheckSum(buf)
  536.  UBYTE *buf;
  537. {
  538.  REGISTER ULONG checksum,i;
  539.  ULONG *long_ptr=(ULONG *)buf;
  540.  for(i=1,checksum=0;i<TD_SECTOR/4;i++) checksum+=long_ptr[i];
  541.  long_ptr[0]=-checksum;
  542. }
  543.  
  544.